/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.
 * 项目名称 : 网站服务平台
 * 创建日期 : 2017-08-21
 * 修改历史 :
 * 1. [2017-08-21]创建文件 by chenxin
 */
package com.gavinwind.inspay.common.advice;

import com.gavinwind.inspay.base.BaseAdvice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 【SpringBoot的web项目Log处理Advice】
 * @author chenxin
 * @date 2017-08-21 下午1:27 
 * @version V1.0
 */
@Aspect
@Component
@Order(1)
public class SpringBootWebLogAdvice extends BaseAdvice {

    ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    //申明一个切点 里面是 execution表达式
    @Pointcut("execution(* com.gavinwind..controller..*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)")
    private void controllerAspect(){}
    //请求method前打印内容
    @Before(value = "controllerAspect()")
    public void methodBefore(JoinPoint joinPoint){
        // 记录当前时间
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //打印请求内容
        logger.info("===============请求内容===============");
        logger.info("请求地址:"+request.getRequestURL().toString());
        logger.info("请求方式:"+request.getMethod());
        logger.info("请求类方法:"+joinPoint.getSignature());
        logger.info("请求类方法参数:"+ Arrays.toString(joinPoint.getArgs()));
        logger.info("===============请求内容===============");
    }
    //在方法执行完结后打印返回内容
    @AfterReturning(returning = "retVal",pointcut = "controllerAspect()")
    public void methodAfterReturing(JoinPoint joinPoint,Object retVal ){
        Long endTime = System.currentTimeMillis();
        Long tDurationTimes = endTime - startTime.get();
        logger.info("--------------返回内容----------------");
        logger.info("请求类方法:"+joinPoint.getSignature().getName());
        logger.info("Response内容:"+retVal);
        logger.info("交易时长:"+tDurationTimes);
        logger.info("--------------返回内容----------------");
    }

    @AfterThrowing(throwing="ex",pointcut="controllerAspect()")
    public void methodThrowException(JoinPoint joinPoint,Throwable ex){
        String tMethodName = joinPoint.getSignature().getName();
        logger.error("--------------异常处理----------------");
        logger.error("目标方法{}中抛出的异常:" + ex,tMethodName);
        logger.error("--------------异常处理----------------");
    }
}
